package com.gjy.jdk.util.concurrent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-11-11 17:35:39
 */
public class ThreadLocalDemo {
    private static final Logger log = LoggerFactory.getLogger(ThreadLocalDemo.class);

    public static void main(String[] args) throws InterruptedException {
        InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
        inheritableThreadLocal.set("World");

        ExecutorService pool = Executors.newFixedThreadPool(1);
        pool.execute(() -> {
            log.info("{}", inheritableThreadLocal.get());
        });

        pool.shutdown();
        log.info("{}", inheritableThreadLocal.get());
    }

    private static void e2() throws InterruptedException {
        ContextHolder.setContext("Hello");

        ContextAwareRunnable runnable = new ContextAwareRunnable(() -> {
            log.info("{}", ContextHolder.getContext());
            ContextHolder.clear();
        });
        new Thread(runnable).start();
        TimeUnit.SECONDS.sleep(1);

        log.info("{}", ContextHolder.getContext());
    }

    private static void e1() {
        ThreadLocal<String> threadLocal = new ThreadLocal<>();
        threadLocal.set("Hello");

        InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
        inheritableThreadLocal.set("World");


        new Thread(() -> {
            log.info("{}", threadLocal.get());
            log.info("{}", inheritableThreadLocal.get());
        }).start();

        log.info("{}", threadLocal.get());
        log.info("{}", inheritableThreadLocal.get());
    }

    static class ContextHolder {
        private static final ThreadLocal<String> context = new ThreadLocal<>();

        public static void setContext(String value) {
            context.set(value);
        }

        public static String getContext() {
            return context.get();
        }

        public static void clear() {
            context.remove();
        }
    }

    static class ContextAwareRunnable implements Runnable {
        private final Runnable target;
        private final String context; // 存储主线程的上下文

        public ContextAwareRunnable(Runnable target) {
            this.target = target;
            // 捕获当前线程（主线程）的上下文
            this.context = ContextHolder.getContext();
        }

        @Override
        public void run() {
            String originalContext = ContextHolder.getContext();
            try {
                // 子线程设置主线程的上下文
                ContextHolder.setContext(context);
                target.run(); // 执行原任务
            } finally {
                // 恢复子线程原有上下文
                ContextHolder.setContext(originalContext);
            }
        }
    }

}
